package com.questionnaire.core.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.questionnaire.config.properties.JwtProperties;
import com.questionnaire.utils.EmptyUtil;
import com.questionnaire.utils.EncodesUtil;
import com.questionnaire.utils.ShiroKit;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 自定义jwtTokken管理器
 * @author: YSL
 * @time: 2023/11/10 15:18
 */
@Service("jwtTokenManager")
@EnableConfigurationProperties({JwtProperties.class })
public class JwtTokenManager {
    @Autowired
    private JwtProperties jwtProperties;
    /**
     * @description: 签发令牌
     * @author: YSL
     * @Param iss 签发者
     * @Param ttlMillis 过期时间
     * @Param claims 隐私信息
     * @time: 2023/11/10 15:18
     */
    public String issuedToken(String iss, Long ttlMillis, String sessionId, Map<String,Object> claims){
        if (EmptyUtil.isNullOrEmpty(claims)){
            claims=new HashMap<>();
        }
//        获取当前时间  构建签名
        long nowMillis=System.currentTimeMillis();
        String base64EncodedSecretKey = EncodesUtil.encodeBase64(jwtProperties.getBase64EncodedSecretKey().getBytes());
//        构建令牌
        JwtBuilder builder = Jwts.builder()
                .setClaims(claims)//非隐私信息
                .setId(sessionId)//唯一生成id
                .setIssuedAt(new Date(nowMillis))//签发时间
                .setSubject(iss)//签发者
                .signWith(SignatureAlgorithm.HS256,base64EncodedSecretKey);//选的算法和签名
        if (ttlMillis>0){
            long expMillis=nowMillis+ttlMillis;
            Date expDate = new Date(expMillis);
//            指定过期时间
            builder.setExpiration(expDate);
        }
        return builder.compact();//返回令牌 token
    }
    /**
     * @description: 解析令牌
     * @author: YSL
     * @Param jwtToken 令牌字符串
     * @time: 2023/11/10 15:18
     */
    public Claims decodeToken(String jwtToken){
//        获取加密签名
        String base64EncodedSecretKey = EncodesUtil.encodeBase64(jwtProperties.getBase64EncodedSecretKey().getBytes());
//        带着密码去解析字符串
        return Jwts.parser()
                .setSigningKey(base64EncodedSecretKey)
                .parseClaimsJws(jwtToken)
                .getBody();
    }
    /**
     * @description: 校验令牌
     * @author: YSL
     * @Param jwtToken 令牌字符串
     * @time: 2023/11/10 15:18
     */
    public boolean isVerifyToken(String jwtToken){

//        构建校验对象 需要签发令牌时的算法一致
        Algorithm algorithm = Algorithm.HMAC256(jwtProperties.getBase64EncodedSecretKey().getBytes());
        JWTVerifier jwtVerifier = JWT.require(algorithm).build();
//        校验  1.不通过 直接抛出异常 2.通过直接return true
        jwtVerifier.verify(jwtToken);
        return true;
    }
}
